package com.guopiao.vat.common.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 工具类
* @ClassName: ToolUtils 
* @author wwm
* @date 2016年8月10日 上午10:16:03 
*
 */
public class ToolUtils
{
	/**
	 * 格式化NULL类型
	* @Title: formatNull 
	* @param @param str
	* @param @return 参数
	* @return String 返回类型
	 */
	public static String formatNull(String str)
	{
		return (str==null)?"":str;
	}
	
	 /**
     * 格式化数字-保留两位小数
    * @Title: formatNumber 
    * @param @param num
    * @param @return 参数
    * @return String 返回类型
     */
    public static String formatNumber(String num)
	{
    	String str = "";
    	if (num ==null || num =="")
		{
    		str = "";
		}
    	else
    	{
    		DecimalFormat df = new DecimalFormat("######0.00");   
    		double dbnum = Double.parseDouble(num.replaceAll(",", ""));
    		str = df.format(dbnum);
		}
  
		return str;
	}
	
	/**
	 * 替换一个字符串中的某些指定字符
	 * 
	 * @param xml String 原始字符串
	 * @param regex String 要替换的字符串
	 * @param replacement String 替代字符串
	 * @return String 替换后的字符串
	 */
	public static String replaceString(String xml, String regex, String replacement)
	{
		if (xml == null)
		{
			return null;
		}
		int index;
		index = xml.indexOf(regex);
		String strNew = "";
		if (index >= 0)
		{
			while (index >= 0)
			{
				strNew += xml.substring(0, index) + replacement;
				xml = xml.substring(index + regex.length());
				index = xml.indexOf(regex);
			}
			strNew += xml;
			return strNew;
		}
		return xml;
	}

	/**
	 * 
	* @Title: encodeString 
	* @param @param xml
	* @param @return 参数
	* @return String 返回类型
	 */
	public static String encodeString(String xml)
	{
		if (xml == null)
		{
			return "";
		}
		xml = replaceString(xml, "&", "&amp;");
		xml = replaceString(xml, "<", "&lt;");
		xml = replaceString(xml, ">", "&gt;");
		xml = replaceString(xml, "&apos;", "&apos;");
		xml = replaceString(xml, "\"", "&quot;");
		return xml;
	}

	/**
	 * 还原字符串中特殊字符
	 */
	public static String decodeString(String xml)
	{
		xml = replaceString(xml, "&lt;", "<");
		xml = replaceString(xml, "&gt;", ">");
		xml = replaceString(xml, "&apos;", "&apos;");
		xml = replaceString(xml, "&quot;", "\"");
		xml = replaceString(xml, "&amp;", "&");
		return xml;
	} 
	
	 /**
     * 删除临时文件
    * @Title: deleteFile 
    * @param @param file 参数
    * @return void 返回类型
     */
	public static void deleteFile(File file)
    { 
        if (file.exists())
        { //判断文件是否存在
            if (file.isFile())
            { //判断是否是文件
                file.delete(); //delete()方法 你应该知道 是删除的意思;
            }
            else if (file.isDirectory())
            { //否则如果它是一个目录
                File files[] = file.listFiles(); //声明目录下所有的文件    files[];
                for (int i=0;i<files.length;i++)
                { //遍历目录下所有的文件
                    //System.out.println(files[i]);
                    deleteFile(files[i]); //把每个文件 用这个方法进行迭代
                } 
            } 
            file.delete();
        }
    }
    
    /**
     * 生成文件名
    * @Title: makeFileName 
    * @param filename
    * @return String 返回类型
     */
    public static String makeFileName(String filename)
	{
		// 为防止文件覆盖的现象发生，要为上传文件产生一个唯一的文件名
		String fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
		return fileName + "_" + filename;
	}
	
    /**
     * 生成文件保存路径
    * @Title: makePath 
    * @param filename
    * @param savePath
    * @param nsrsbh
    * @return String 返回类型
     */
    public static String makePath(String filename, String savePath,String nsrsbh)
	{
		// 得到文件名的hashCode的值，得到的就是filename这个字符串对象在内存中的地址
//				int hashcode = filename.hashCode();
		
		String dir1 = new SimpleDateFormat("yyyy-MM-dd").format(new Date());//文件目录1
		String dir2 = nsrsbh;//公司税号
		
		// 构造新的保存目录
		String dir = savePath + "\\" + dir1 + "\\" + dir2; 
		
		// File既可以代表文件也可以代表目录
		File file = new File(dir);
		// 如果目录不存在
		if (!file.exists())
		{
			// 创建目录
			file.mkdirs();
		}
		return dir;
	}
    
    /**
     * 小数转百分数
    * @Title: formatBfs 
    * @param @param xs
    * @param @param num 保留小数位
    * @param @return 参数
    * @return String 返回类型
     */
    public static String formatBfs(String xs,int num)
	{
    	NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMaximumFractionDigits(num);//这个1的意识是保存结果到小数点后几位，但是特别声明：这个结果已经先＊100了。
		return nf.format(Double.parseDouble(xs));
	}
    
    /**
     * 百分数转小数
    * @Title: formatXs 
    * @param @param str 百分数
    * @param @param num 保留小数位
    * @param @return 参数
    * @return String 返回类型
     * @throws ParseException 
     */
    public static String formatXs(String str)
	{
    	NumberFormat nf = NumberFormat.getPercentInstance();
        String xs = "";
		try
		{
			xs = nf.parse(str).toString();
		} catch (ParseException e)
		{
			e.printStackTrace();
		}
		return xs;
	}
    
    
	private static final String UNIT = "万仟佰拾亿仟佰拾万仟佰拾元角分";
	private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖";
	private static final double MAX_VALUE = 9999999999999.99D;

	/**
	 * 小写金额转大写金额
	* @Title: formatMonry 
	* @param @param v
	* @param @return 参数
	* @return String 返回类型
	 */
	public static String formatMonry(double v)
	{
		boolean flag = (v < 0)?true:false;//是否为负数
		
		if (v > MAX_VALUE)
		{
			return "参数非法!";
		}
		if (flag)
		{
			v = Math.abs(v);//取绝对值
		}
		
		long l = Math.round(v * 100);
		if (l == 0)
		{
			return "零元整";
		}
		String strValue = l + "";
		int i = 0;// i用来控制数
		int j = UNIT.length() - strValue.length();// j用来控制单位
		String rs = "";
		boolean isZero = false;
		for (; i < strValue.length(); i++, j++)
		{
			char ch = strValue.charAt(i);
			if (ch == '0')
			{
				isZero = true;
				if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元')
				{
					rs = rs + UNIT.charAt(j);
					isZero = false;
				}
			} else
			{
				if (isZero)
				{
					rs = rs + "零";
					isZero = false;
				}
				rs = rs + DIGIT.charAt(ch - '0') + UNIT.charAt(j);
			}
		}
		
		if (!rs.endsWith("分"))
		{
			rs = rs + "整";
		}
		
		rs = rs.replaceAll("亿万", "亿");
		if (flag)
		{
			rs = "(负数)"+ rs;
		}
		return rs;
	}
	
	public static String checkStrTo4(String bm)
	{
		if (bm.length() < 4)
		{
			String bw = "";
			for (int i = 0; i < 4-bm.length(); i++)
			{
				bw += "0";
			}
			bm = bw+bm;
		}
		
		return bm;
	}
	
	/** 
     * 将一个 JavaBean 对象转化为一个  Map 
     * @param bean 要转化的JavaBean 对象 
     * @return 转化出来的  Map 对象 
     * @throws IntrospectionException 如果分析类属性失败 
     * @throws IllegalAccessException 如果实例化 JavaBean 失败 
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败 
     */  
    @SuppressWarnings({ "rawtypes", "unchecked" })  
	public static Map convertBean(Object bean) throws IntrospectionException, IllegalAccessException, InvocationTargetException
	{
		Class type = bean.getClass();
		Map returnMap = new HashMap();
		BeanInfo beanInfo = Introspector.getBeanInfo(type);

		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++)
		{
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
			if (!propertyName.equals("class"))
			{
				Method readMethod = descriptor.getReadMethod();
				Object result = readMethod.invoke(bean, new Object[0]);
				if (result != null)
				{
					returnMap.put(propertyName, result);
				} else
				{
					returnMap.put(propertyName, "");
				}
			}
		}
		return returnMap;
	}

    /** 
     * 将一个 Map 对象转化为一个 JavaBean 
     * @param type 要转化的类型 
     * @param map 包含属性值的 map 
     * @return 转化出来的 JavaBean 对象 
     * @throws IntrospectionException 如果分析类属性失败 
     * @throws IllegalAccessException 如果实例化 JavaBean 失败 
     * @throws InstantiationException 如果实例化 JavaBean 失败 
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败 
     */  
    @SuppressWarnings("rawtypes")  
	public static Object convertMap(Class type, Map map) throws IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException
	{
		BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
		Object obj = type.newInstance(); // 创建 JavaBean 对象

		// 给 JavaBean 对象的属性赋值
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++)
		{
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName().toLowerCase();

			if (map.containsKey(propertyName) || map.containsKey(propertyName.toUpperCase()))
			{
				// 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
				Object value = map.get(propertyName);
				if (value==null || "".equals(value))
				{
					value = map.get(propertyName.toUpperCase());
				}

				Object[] args = new Object[1];
				if ("kprq".equals(propertyName)) //开票日期特殊处理
				{
					value = value+"";
				}
				
				args[0] = value;
				descriptor.getWriteMethod().invoke(obj, args);
			}
		}
		return obj;
	}

//	/**
//	 * 发票短信工具类
//	 * @Title: pushSms2Bridege
//	 * @param @param reqxml 短信内容
//	 * @param @param smsurl 短信地址
//	 * @param @return
//	 * @param @throws IOException 参数
//	 * @return Map<String,Object> 返回类型
//	 */
//	@SuppressWarnings("unchecked")
//	public static Map<String, Object> pushSms2Bridege(String reqxml,String smsurl) throws IOException
//	{
//		Map<String, Object> returnMap = new HashMap<String, Object>();
//		URL url = null;
//		try
//		{
//			url = new URL(smsurl);
//			URLConnection connection = url.openConnection();
//			connection.setDoOutput(true);
//			OutputStreamWriter out = new OutputStreamWriter( connection.getOutputStream(), "utf-8");
//
//			reqxml = UrlEncoded.encodeString(reqxml, "utf-8");
//			out.write("xmlData=" + reqxml);
//			out.flush();
//			out.close();
//
//			String sCurrentLine;
//			String sTotalString;
//			sCurrentLine = "";
//			sTotalString = "";
//			InputStream l_urlStream;
//			l_urlStream = connection.getInputStream();
//			BufferedReader l_reader = new BufferedReader(new InputStreamReader(l_urlStream));
//			while ((sCurrentLine = l_reader.readLine()) != null)
//			{
//				sTotalString += sCurrentLine + "\r\n";
//			}
//			/**
//			 * <?xml version="1.0" encoding="gbk"?><business id="10003" comment="生成待发短信记录">
//			 * <body>
//			 * <returncode>0</returncode>
//			 * <returnmsg>成功</returnmsg>
//			 * </body>
//			 * </business>
//			 */
//			Map<String, Object> smsMap = Dom4jUtil.Xml2Map(sTotalString);
//			Map<String, Object> bodyMap = (Map<String, Object>) smsMap.get("body");
//			String rtncode = (String) bodyMap.get("returncode");
//			if ("0".equals(rtncode))
//			{
//				returnMap.put("rtnCode", "0");
//				returnMap.put("rtnMsg", "短信发送成功，请注意查收！");
//			}
//			else
//			{
//				returnMap.put("rtnCode", "-1");
//				returnMap.put("rtnMsg", "短信发送失败，原因："+smsMap.get("returncode"));
//			}
//		}
//		catch (MalformedURLException e)
//		{
//			e.printStackTrace();
//			returnMap.put("rtnCode", "-1");
//			returnMap.put("rtnMsg", "短信发送失败，原因："+e.getMessage());
//		} catch (Exception e) {
//			e.printStackTrace();
//			returnMap.put("rtnCode", "-1");
//			returnMap.put("rtnMsg", "短信发送失败，原因："+e.getMessage());
//		}
//		return returnMap;
//	}

//	/**
//	 * Bean转Map
//	 * @param obj
//	 * @return
//	 */
//	public static Map<String, Object> beanToMap(Object obj) throws Exception
//	{
//		Map<String, Object> params = new HashMap<String, Object>(0);
//		PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
//		PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(obj);
//		for (int i = 0; i < descriptors.length; i++) {
//			String name = descriptors[i].getName();
//			if (!"class".equals(name))
//			{
//				Object value = propertyUtilsBean.getNestedProperty(obj, name);;
//				params.put(name, value);
//			}
//		}
//
//		return params;
//	}

	public static boolean isNull(Object obj)
	{
		boolean isNullFlag = true;
		if (obj != null)
			if (obj instanceof List)
				isNullFlag = isNull((List)obj);
			else if (obj instanceof Set)
				isNullFlag = isNull((Set)obj);
			else if (obj instanceof Object[])
				isNullFlag = isNull((Object[])(Object[])obj);
			else if (obj instanceof Map)
				isNullFlag = isNull((Map)obj);
			else if (obj instanceof String)
				isNullFlag = isNull((String)obj);
			else
				isNullFlag = false;


		return isNullFlag;
	}

	public static boolean isNull(List<?> list)
	{
		return ((list == null) || (list.size() == 0));
	}

	public static boolean isNull(Set<?> set)
	{
		return ((set == null) || (set.size() == 0));
	}

	public static boolean isNull(Object[] objects)
	{
		return ((objects == null) || (objects.length == 0));
	}

	public static boolean isNull(Map<?, ?> map)
	{
		return ((map == null) || (map.isEmpty()));
	}

	public static boolean isNull(String str)
	{
		return ((str == null) || ("".equals(str.trim())) || ("null".equalsIgnoreCase(str.trim())));
	}
}
